package com.tjetc.controller;

import cn.hutool.json.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeRefundApplyModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.tjetc.config.AlipayConfig;
import com.tjetc.domain.enums.OrderStatus;
import com.tjetc.domain.po.Orders;
import com.tjetc.domain.vo.BackVO;
import com.tjetc.domain.vo.OrderVo;
import com.tjetc.service.IOrdersService;
import com.tjetc.utils.BloomFilterInit;
import com.tjetc.utils.PoToVoUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.Map;

@RestController
@CrossOrigin
@RequestMapping("/alipay")
public class AliPayController {

    private static final String GATEWAY_URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
    private static final String FORMAT = "JSON";
    private static final String CHARSET = "UTF-8";
    private static final String SIGN_TYPE = "RSA2";

    @Resource
    private AlipayConfig alipayConfig;

    @Resource
    private IOrdersService orderService;


    @Resource
    private PoToVoUtil poToVoUtil;

    @GetMapping("/pay")
    public void pay(String orderNo, HttpServletResponse httpResponse) {
        //查询订单信息
        Orders orders = orderService.selectByOrderNo(orderNo);
        if (orders == null) {
            return;
        }
        //1.创建Client  通用SDK提供的Client  负责调用支付宝API
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, alipayConfig.getAppId(),
                alipayConfig.getAppPrivateKey(), FORMAT, CHARSET, alipayConfig.getAlipayPublicKey(), SIGN_TYPE);

        //2.创建Request 并设置参数
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest(); //发送请求的 Request类
        request.setNotifyUrl(alipayConfig.getNotifyUrl());
        JSONObject bizContent = new JSONObject();
        bizContent.set("out_trade_no", orders.getOrderNo());
        bizContent.set("total_amount", orders.getTotal());
        bizContent.set("subject", "门票");
        bizContent.set("product_code", "FAST_INSTANT_TRADE_PAY");
        request.setBizContent(bizContent.toString());
        request.setReturnUrl("http://localhost:5173/");  //支付完成后自动跳转到本地路径
        //执行请求  拿到响应结果 返回给浏览器
        String form = "";
        try {
            form = alipayClient.pageExecute(request).getBody(); //调用SDK生成表单
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        try {
            httpResponse.setContentType("text/html;charset=" + CHARSET);
            httpResponse.getWriter().write(form);
            httpResponse.getWriter().flush();
            httpResponse.getWriter().close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Transactional
    @PostMapping("/notify")
    public void payNotify(HttpServletRequest request) throws Exception {

        if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {

            System.out.println("=======支付宝异步回调=======");
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                params.put(name, request.getParameter(name));
            }
            String sign = params.get("sign");
            String content = AlipaySignature.getSignCheckContentV1(params);
            boolean checkSignature = AlipaySignature.rsa256CheckContent(content, sign, alipayConfig.getAlipayPublicKey(), "UTF-8");

            //支付宝验签
            if (checkSignature) {
                //验签通过
                System.out.println("交易名称" + params.get("subject"));
                System.out.println("交易状态" + params.get("trade_status"));
                System.out.println("支付宝交易凭证号" + params.get("trade_no"));
                System.out.println("商户订单号" + params.get("out_trade_no"));
                System.out.println("交易金额" + params.get("total_amount"));
                System.out.println("买家再支付宝的唯一id" + params.get("buyer_id"));
                System.out.println("买家付款时间" + params.get("amt_payment"));
                System.out.println("买家付款金额" + params.get("buyer_pay_amount"));
                String tradeNo = params.get("out_trade_no");  //订单编号
                String gmtPayment = params.get("gmt_payment");  //支付时间
                String alipayTradeNo = params.get("trade_no");  //支付宝交易编号
                //更新订单状态为已支付  设置支付信息
                Orders orders = orderService.selectByOrderNo(tradeNo);
                orders.setStatus(OrderStatus.getOrderStatus("已支付").getNum());
                orders.setPayTime(LocalDateTime.parse(gmtPayment, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                orders.setPayNo(alipayTradeNo);
                orderService.updateById(orders);

            }


        }

    }

    @GetMapping("/back")
    public String back(String orderNo) throws AlipayApiException {
        Orders orders = orderService.selectByOrderNo(orderNo);
        if (orders == null) {
            return "订单号不存在，退款失败";
        }


        if (!orders.getStatus().equals(OrderStatus.getOrderStatus("已支付").getNum())){
            return "订单状态不是已支付,退款失败";
        }

        BackVO backVO = orderService.findStartTime(orderNo);

        if (LocalDateTime.now().isAfter(backVO.getStartTime())){
            return "演唱会已经开始了，退款失败";
        }

        if (Duration.between(LocalDateTime.now(), backVO.getStartTime()).toHours()<2){
            return "离演唱会开始不足两小时，退款失败";
        }


        //1.创建Client  通用SDK提供的Client  负责调用支付宝API
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, alipayConfig.getAppId(),
                alipayConfig.getAppPrivateKey(), FORMAT, CHARSET, alipayConfig.getAlipayPublicKey(), SIGN_TYPE);
        /*调用支付宝*/
        AlipayTradeRefundRequest alipayTradeCloseRequest = new AlipayTradeRefundRequest();
        /*请求参数集合*/
        AlipayTradeRefundModel alipayTradeRefundModel = new AlipayTradeRefundModel();
        /*退款订单号*/
        alipayTradeRefundModel.setOutTradeNo(orderNo);
        /*退款金额*/
        alipayTradeRefundModel.setRefundAmount(String.valueOf(orders.getTotal()));
        /*退款原因*/
        alipayTradeRefundModel.setRefundAdvanceAccount("爷傲奈我何");
        alipayTradeCloseRequest.setBizModel(alipayTradeRefundModel);
        AlipayTradeRefundResponse response = alipayClient.execute(alipayTradeCloseRequest);

        /*判断资金是否发生变化，equals("Y")表示资金发生了变化，退款成功*/
        if (response.isSuccess()) { //退款接口调用成功
            if (response.getFundChange().equals("Y")) {  //资金发生了变化，退款成功
                orders.setStatus(OrderStatus.getOrderStatus("已退款").getNum());
                orders.setBackTime(LocalDateTime.now());
               return   orderService.backMoney(orders);
            }
        }

        return "退款成功";
    }


}


